package com.gframework.util;

import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * lambda表达式对象相关操作工具类.
 * 
 * @since 2.0.0
 * @author Ghwolf
 */
public class LambdaUtils {

	private LambdaUtils() {
	}

	/**
	 * 获取一个lambda表达式对象的SerializedLambda序列化对象
	 * 
	 * @param functionInterface lambda表达式对象，不能为null
	 * @return 返回lamdba序列化对象，如果不是一个合法的lambda对象，则抛出异常
	 * @throws IllegalArgumentException
	 *             如果不是一个lambda接口对象或者函数式接口没有实现{@link Serializable}接口。
	 */
	public static SerializedLambda getSerializedLambda(Serializable functionInterface) throws IllegalArgumentException {
		Class<?> fiClass = functionInterface.getClass();
		if (!fiClass.isSynthetic()) {
			throw new IllegalArgumentException(fiClass + " 不是一个lambda接口对象！");
		}
		try {
			Method m = fiClass.getDeclaredMethod("writeReplace");
			m.setAccessible(true);
			return (SerializedLambda) m.invoke(functionInterface);
		} catch (NoSuchMethodException e) {
			throw new IllegalArgumentException(fiClass + " 不是一个lambda接口对象，或者他没有实现Serializable接口！");
		} catch (IllegalAccessException e) {
			// Ignore
			throw new IllegalArgumentException(e);
		} catch (IllegalArgumentException e) {
			throw new IllegalArgumentException("writeReplace是Serializable接口子类的特有方法，请不要主动使用此名字作为方法名称！", e);
		} catch (InvocationTargetException e) {
			throw new IllegalArgumentException("获取lambda对象信息异常！", e);
		}
	}
}
